from ubr import query_positions, query_job_detail
from ubr import LANGUAGE_EN_US, LANGUAGE_ZH_CN
import pymysql
import db 
import time
import json
from tc import send_push
from subscriptions import get_subscribers, broadcast_push, broadcast_push_to_subscribers

def main():
  print('[>] SYNC START')
  records_remote = convert_map(query_all_positions(), 'id')
  records_local = convert_map(db.fetch_all_positions(), 'ubr_id')
  print('[*] Remote / Local = %d / %d' % (len(records_remote), len(records_local)))
  print('[*] DATABASE ---> ')
  db_conn = db.get_conn()
  db_c = db_conn.cursor(cursor=pymysql.cursors.DictCursor)
  print('[*] ............ OKAY')
  print('[*] COMPARING... ')
  list_changes = []
  list_removed = []
  count_new = 0
  count_update = 0
  count_removed = 0
  for remote_job_id in records_remote:
    remote_job = records_remote[remote_job_id]
    if remote_job_id in records_local:
      # compare time
      if records_local[remote_job_id]['date'] != remote_job['date']:
        list_changes.append({'job': remote_job, 'update': True})
        count_update += 1
    else:
      list_changes.append({'job': remote_job, 'update': False})
      count_new += 1
  for local_job_id in records_local:
    if local_job_id not in records_remote:
      count_removed += 1
      list_removed.append(records_local[local_job_id])
  print('[#] NEW JOBS: %d' % count_new)
  print('[#] UPDATED JOBS: %d' % count_update)
  print('[#] REMOVED JOBS: %d' % count_removed)
  print('[*] SAVING... ')
  for change in list_changes:
    job = change['job']
    record_type = db.TYPE_NEW
    if change['update']:
      db_c.execute(db.SQL_DELETE_POSITION, [job['id']])
      record_type = db.TYPE_UPDATED
    print('[*] QUERYING DESC FOR UBR JOB ID [#%s]... ' % str(job['id']))
    print('      - en_US')
    job_desc_en = query_job_detail(job['id'], LANGUAGE_EN_US)
    if job_desc_en is not False:
      print('               ok')
    else:
      print('               FAIL')
    print('      - zh_CN')
    job_desc_zh = query_job_detail(job['id'], LANGUAGE_ZH_CN)
    if job_desc_zh is not False:
      print('               ok')
    else:
      print('               FAIL')
    db_c.execute(db.SQL_INSERT_POSITION, [
                    job['id'], 
                    job['date'],
                    job['title'],
                    job['depart'],
                    job['dcode'],
                    job_desc_en,
                    job_desc_zh
                ])
    db_c.execute(db.SQL_INSERT_POSITION_LOG, [job['id'], record_type, int(time.time()), json.dumps(job), job_desc_en, job_desc_zh])
  for removed in list_removed:
    removed['id'] = removed['ubr_id']
    del removed['ubr_id']
    db_c.execute(db.SQL_DELETE_POSITION, [removed['id']])
    db_c.execute(db.SQL_INSERT_POSITION_LOG, [removed['id'], db.TYPE_REMOVED, json.dumps(removed), None, None])
  db_conn.commit()
  print('[*] DATA SAVED')
  print('[*] SENDING PUSH NOTIFICATION')
  process_push(list_changes, list_removed, count_new, count_update, count_removed)
  print('[<] ALL COMPLETE! ')

def process_push(changes, removed, count_new, count_update, count_removed):
  count_total = count_new + count_update + count_removed
  if count_total == 0:
    print('[*] ............... NO UPDATES, NOT SENDING')
    return
  subj = 'UBR [+ %d] [- %d] [# %d]\n' % (count_new, count_removed, count_update)
  body = ''
  if count_new > 0:
    body += '# New >> '
    for k in changes:
      if k['update']:
        continue
      body += k['job']['title']
      body += '; '
    body += '\n'
  if count_update > 0:
    body += '# Changed >> '
    for k in changes:
      if not k['update']:
        continue
      body += k['job']['title']
      body += '; '
    body += '-------------------\n'
  if count_removed > 0:
    body += 'Removed: \n'
    for r in removed:
      body += r['title']
      body += '; '
    body += '=-=-=-=-=-=-=-=-=-='
  send_push('UBR Watch Service', subj[:100], body[:2000])
  print('SENDING TO SUBSCRIBERS... ')
  broadcast_push_to_subscribers( subj[:100], body[:2000])

def convert_map(jobs, key):
  ret = {}
  for x in jobs:
    ret[x[key]] =x
  return ret

def query_all_positions():
  # print('Reading first page... ')
  first_page = query_positions(1)
  if first_page == None:
    print('Failed querying first page! ')
    return
  all_positions = first_page['data']
  rec_total = first_page['total']
  rec_left = rec_total - len(first_page['data'])
  page = 1

  #print('Page %d' % page, ', positions: %d' % len(first_page['data']))

  while rec_left > 0:
    page += 1
    page_data = query_positions(page)
    if page_data == None:
      print('Failed querying page <%d>, PROGRAM STOPPED! ' % page)
      return
    rec_found = len(page_data['data'])
    rec_left -= rec_found
    # print('Page %d' % page, ', positions: %d' % rec_found)
    all_positions.extend(page_data['data'])
  return all_positions
'''
  print('===============================')
  print('Found totally <%d> positions! ' % len(all_positions))
  print('===============================')
  print('Job ID'.center(8) + ' | Title')
  for pos in all_positions:
    print('ID %s | [%s]' % (pos['id'].center(6), pos['title']))
'''

if __name__ == '__main__':
  main()
